﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Surface.Core;
using Microsoft.Surface.Core.Manipulations;
using Microsoft.Xna.Framework.Input;

namespace Sublimation
{
    class MenuSurf : Menu
    {
        protected const int MAXNUMTOWERS = 3;
        protected List<PreviewTower> previewTowerList;
        public List<PreviewTower> PreviewTowerList
        {
            get { return previewTowerList; }
            set { previewTowerList = value; }
        }
        protected List<PreviewTowerItem> previewTowerItemList;
        public List<PreviewTowerItem> PreviewTowerItemList
        {
            get { return previewTowerItemList; }
            set { previewTowerItemList = value; }
        }
        protected float prevOrientation;
        public float PrevOrientation
        {
            get { return prevOrientation; }
            set { prevOrientation = value; }
        }
        protected float prevX;
        protected float prevY;
        protected Contact contact;

        protected bool addingTower;
        public bool AddingTower
        {
            get { return addingTower; }
            set { addingTower = value; }
        }
        protected PreviewTower curPreviewTower;
        public PreviewTower CurPreviewTower
        {
            get { return curPreviewTower; }
            set { curPreviewTower = value; }
        }
        protected PreviewTowerItem curPreviewTowerItem;
        public PreviewTowerItem CurPreviewTowerItem
        {
            get { return curPreviewTowerItem; }
            set { curPreviewTowerItem = value; }
        }

        public Contact Contact
        {
            get { return contact; }
            set { contact = value; }
        }

        public MenuSurf(WorldProperties worldProperties,Contact contact,Vector2 origin)
            : base(worldProperties)
        {
            this.contact = contact;
            this.origin = origin;
            previewTowerList = new List<PreviewTower>();
            previewTowerItemList = new List<PreviewTowerItem>();
            addingTower = false;
        }

        public void InitialisePreviewTowerItems(List<Tower> curTowers)
        {
             int towerCount = curTowers.Count();
            // Construct the built towers icons first

            for (int i = 0; i < towerCount; i++)
            {
                if (previewTowerItemList.Count == 0)
                {
                    PreviewTowerItem newItem = new PreviewTowerItem(worldProperties, this,
                            new Vector2(Position.X + menuSideMargin, Position.Y + topMargin),
                            new Vector2(0, 0), PreviewTowerKind.Built,curTowers[i]);
                    newItem.Center = new Vector2(newItem.Position.X + newItem.Sprite.Width / 2
                        , newItem.Position.Y + newItem.Sprite.Height / 2);
                    menuItems.Add(newItem);
                    previewTowerItemList.Add(newItem);
                }
                else
                {
                    MenuItemSurf lastAdded = (MenuItemSurf)menuItems.Last();

                    PreviewTowerItem newItem = new PreviewTowerItem(worldProperties, this,
                        new Vector2(lastAdded.Position.X + lastAdded.Sprite.Width + itemSideMargin,
                            lastAdded.Position.Y),
                        new Vector2(0, 0), PreviewTowerKind.Built, curTowers[i]);
                    newItem.Center = new Vector2(newItem.Position.X + newItem.Sprite.Width / 2
                        , newItem.Position.Y + newItem.Sprite.Height / 2);
                    menuItems.Add(newItem);
                    previewTowerItemList.Add(newItem);
                }
            // then construct the icons for available to built and add button icons
            }
            for (int i = towerCount; i < MAXNUMTOWERS; i++)
            {
                if (previewTowerItemList.Count == towerCount)
                {
                    if (towerCount == 0)
                    {
                        PreviewTowerItem newItem = new PreviewTowerItem(worldProperties, this,
                            new Vector2(Position.X + menuSideMargin, Position.Y + topMargin),
                            new Vector2(0, 0), PreviewTowerKind.Add, null);
                        newItem.Center = new Vector2(newItem.Position.X + newItem.Sprite.Width / 2
                        , newItem.Position.Y + newItem.Sprite.Height / 2);
                        menuItems.Add(newItem);
                        previewTowerItemList.Add(newItem);
                    }
                    else
                    {
                        MenuItemSurf lastAdded = (MenuItemSurf)menuItems.Last();

                        PreviewTowerItem newItem = new PreviewTowerItem(worldProperties, this,
                            new Vector2(lastAdded.Position.X + lastAdded.Sprite.Width + itemSideMargin,
                                lastAdded.Position.Y),
                            new Vector2(0, 0), PreviewTowerKind.Add, null);
                        newItem.Center = new Vector2(newItem.Position.X + newItem.Sprite.Width / 2
                        , newItem.Position.Y + newItem.Sprite.Height / 2);
                        menuItems.Add(newItem);
                        previewTowerItemList.Add(newItem);
                    }
                }
                else
                {
                    MenuItemSurf lastAdded = (MenuItemSurf)menuItems.Last();

                    PreviewTowerItem newItem = new PreviewTowerItem(worldProperties, this,
                        new Vector2(lastAdded.Position.X + lastAdded.Sprite.Width + itemSideMargin,
                            lastAdded.Position.Y),
                        new Vector2(0, 0), PreviewTowerKind.Unbuilt, null);
                    newItem.Center = new Vector2(newItem.Position.X + newItem.Sprite.Width / 2
                        , newItem.Position.Y + newItem.Sprite.Height / 2);
                    menuItems.Add(newItem);
                    previewTowerItemList.Add(newItem);
                }
            }
        }

        public void InitialisePreviewTowers(List<Tower> curTowers)
        {
            Vector2 previewTowerPos =  new Vector2(this.Position.X , this.Position.Y);
            Vector2 posInc = new Vector2(35,55);
            previewTowerPos += posInc;

            int towerCount = curTowers.Count();

            for (int i = 0; i < towerCount; i++)
            {
                Tower aTower = null;
                if (i < towerCount)
                {
                    aTower = curTowers[i];
                }
                // Just for the defult view no interaction
                PreviewTower defaultPreviewTower = new PreviewTower(worldProperties, this, previewTowerPos, new Vector2(0, 0), 0.0f,aTower);

                defaultPreviewTower.Position = RotatePoint(this.Position, this.Rotation, defaultPreviewTower.Position);
                defaultPreviewTower.Center = RotatePoint(this.Position, this.Rotation, defaultPreviewTower.Center);
                defaultPreviewTower.DeltaRotation = this.Rotation;
                defaultPreviewTower.Rotation += this.Rotation;

                defaultPreviewTower.Visible = false;
                menuItems.Add(defaultPreviewTower);
                previewTowerList.Add(defaultPreviewTower);
            }
        }

        // find the preview tower associated to tower
        public PreviewTower FindPreviewTower(Tower aTower)
        {
            foreach (PreviewTower aItem in previewTowerList)
            {
                if (aItem.CurTower != null)
                {
                    if (aItem.CurTower.Equals(aTower))
                    {
                        return aItem;
                    }
                }
            }
            return null;
        }

        public PreviewTowerItem FindPreviewTowerItem(Tower aTower)
        {
            foreach (MenuItem aItem in MenuItemList)
            {
                if (aItem is PreviewTowerItem)
                {
                    PreviewTowerItem previewTowerItem = (PreviewTowerItem)aItem;
                    Tower curTower = previewTowerItem.OriginTower;
                    if (curTower != null)
                    {
                        if (curTower.Equals(aTower))
                        {
                            return previewTowerItem;
                        }
                    }
                }
            }
            return null;
        }

        public void CheckTowerCollision(Vector2 tagPosition)
        {
            bool check = false;
            Tower collidedTower = null;
            foreach (Tower aTower in worldProperties.Players[0].Towers)
            {
                if (Vector2.Distance(aTower.Position, tagPosition) < aTower.CollisionRadius)
                {
                    check = true;
                    collidedTower = aTower;
                    break;
                }
            }
            if (check)
            {
                PreviewTower newPreviewTower = this.FindPreviewTower(collidedTower);

                if (newPreviewTower != null)
                {
                    if (!newPreviewTower.Equals(curPreviewTower))
                    {
                        if (curPreviewTower != null && curPreviewTowerItem != null)
                        {
                            curPreviewTower.SetVisible(false);
                            curPreviewTowerItem.ItemStatus = MenuItemStatus.Unselected;
                        }

                        // make the collided tower items selected  and visible
                        curPreviewTower = newPreviewTower;
                        if (curPreviewTower != null)
                        {
                            curPreviewTower.SetVisible(true);
                        }
                        curPreviewTowerItem = this.FindPreviewTowerItem(collidedTower);
                        if (curPreviewTowerItem != null)
                        {
                            curPreviewTowerItem.ItemStatus = MenuItemStatus.Selected;
                        }
                    }
                }
            }

        }

        public void ClearSelectedItems()
        {
            foreach (MenuItem item in MenuItemList)
            {
                if (item is PreviewTowerItem)
                {
                    item.ItemStatus = MenuItemStatus.Unselected;
                    Tower orgTower = ((PreviewTowerItem)item).OriginTower;
                    if (orgTower != null)
                    {
                        orgTower.SpriteColor = Color.White;

                        // make other pre tower displays disable
                        PreviewTower otherPreTower = FindPreviewTower(orgTower);
                        if (otherPreTower != null)
                            otherPreTower.SetVisible(false);
                    }
                }
            }
        }
       
        public void AddTowerAddItem()
        {
            if (menuItems.Count == 0)
            {
                MenuItemSurf newItem = new MenuItemSurf(worldProperties, this,
                    new Vector2(Position.X + menuSideMargin, Position.Y + topMargin),new Vector2(0, 0));
                newItem.Center = new Vector2(newItem.Position.X + newItem.Sprite.Width / 2
                        , newItem.Position.Y + newItem.Sprite.Height / 2);
                menuItems.Add(newItem);
                newItem.Position = RotatePoint(this.Position, this.Rotation, newItem.Position);
                newItem.Center = RotatePoint(this.Position, this.Rotation, newItem.Center);
                newItem.DeltaRotation = this.Rotation;
                newItem.Rotation += this.Rotation;
            }
        }

        public void AddPreviewTower(Tower aTower)
        {
            Vector2 previewTowerPos = new Vector2(this.Position.X, this.Position.Y);
            Vector2 posInc = new Vector2(35, 55);
            PreviewTower newPreviewTower = new PreviewTower(worldProperties, 
                this, previewTowerPos + posInc,Vector2.Zero,0.0f , aTower);
   
            //newPreviewTower.Center += posInc;
            newPreviewTower.Position = RotatePoint(this.Position, this.Rotation, newPreviewTower.Position);
            newPreviewTower.Center = RotatePoint(this.Position, this.Rotation, newPreviewTower.Center);
            newPreviewTower.DeltaRotation = this.Rotation;
            newPreviewTower.Rotation = this.Rotation;
            newPreviewTower.SetVisible(false);
            menuItems.Add(newPreviewTower);
            previewTowerList.Add(newPreviewTower);
            // update the preview tower item list 
            UpdatePreviewTowerItemList();

        }
        public void AddPreviewTowerItem(Tower originTower, int towerAddIndex)
        {
            int addItemIndex = towerAddIndex;

            MenuItemSurf tempItem = (MenuItemSurf)menuItems.ElementAt(addItemIndex);
            PreviewTowerItem addButton = (PreviewTowerItem)tempItem;
            addButton.Kind = PreviewTowerKind.Built;
            addButton.OriginTower = originTower;

            if (addItemIndex != MAXNUMTOWERS - 1)
            {
                tempItem = (MenuItemSurf)menuItems.ElementAt(addItemIndex + 1);
                PreviewTowerItem unBuiltButton = (PreviewTowerItem)tempItem;
                unBuiltButton.Kind = PreviewTowerKind.Add;
            }  
        }

        // Method for rotating and translating the huds
        public void Transform(Contact aContact)
        {
            // current hud position
            float curX = aContact.X;
            float curY = aContact.Y;

            float deltaX;
            float deltaY;

            if (prevX != 0.0f && prevY != 0.0f)
            {
                // translation deltas 
                deltaX = curX - prevX;
                deltaY = curY - prevY;
            }
            else
            {
                deltaX = 0.0f;
                deltaY = 0.0f;
            }

            // save x,y values
            prevX = curX;
            prevY = curY;

            // translate the hud to current point 
            this.Position = new Vector2(curX, curY);

            for(int i = 0 ; i < menuItems.Count; i++)
            {
                MenuItemSurf aItem = (MenuItemSurf)menuItems.ElementAt(i);
                aItem.Translate(new Vector2(deltaX, deltaY));
                if (aItem is PreviewTower)
                {
                    ((PreviewTower)aItem).TranslateSlots(new Vector2(deltaX, deltaY));
                }
            }

            float currentOrientation = aContact.Orientation % MathHelper.TwoPi;

            if (prevOrientation != 0.0f)
            {
                // rotation delta
                float deltaRotation = currentOrientation - prevOrientation;
                // rotate the hud container
                rotation += deltaRotation;
                AlignAllItems(deltaRotation);
            }

            // save current rotation
            prevOrientation = currentOrientation;

        }

        public void AlignAllItems(float deltaRotation)
        {
            // align each item related to rotation
            for (int i = 0; i < menuItems.Count; i++)
            {
                MenuItemSurf aItem = (MenuItemSurf)menuItems.ElementAt(i);


                if (aItem is PreviewTower)
                {
                    ((PreviewTower)aItem).RotateSlots(deltaRotation);
                }
                    aItem.Rotate(deltaRotation);
                    
            }
        }

        public void AlignPreTowerItems(float deltaRotation)
        {
            // align each item related to rotation
            for (int i = 0; i < menuItems.Count; i++)
            {
                MenuItemSurf aItem = (MenuItemSurf)menuItems.ElementAt(i);


                if (!(aItem is PreviewTower))
                {
                    aItem.Rotate(deltaRotation);
                    //((PreviewTower)aItem).RotateSlots(deltaRotation);
                }
                

            }
        }

        // checks if it menu contains the contact. 
        public bool Contains(Tower aTower)
        {
            Vector2 point = new Vector2(aTower.Position.X, aTower.Position.Y);
            float curRotation = this.Rotation;

            // if the item is rotated
            if (curRotation != 0)
            {
                point = RotatePoint(this.Position, (float)(2 * Math.PI) - curRotation, point);
            }

            return ContainsPoint(point);
        }

        // Update Preview Tower Items List 
        public void UpdatePreviewTowerItemList()
        {
            List<PreviewTowerItem> list = this.PreviewTowerItemList;

            /* iterate to clear the refences in menu item list */
            for (int i = 0; i < list.Count(); i++)
            {
                PreviewTowerItem curDelItem = list.ElementAt(i);
                // remove it also from menu list
                this.MenuItemList.Remove(curDelItem);
                curDelItem.OriginTower = null;
                curDelItem.Kill();
            }

            this.PreviewTowerItemList.Clear();
            // initialise the list again
            this.InitialisePreviewTowerItems(worldProperties.Players[0].Towers);
            AlignPreTowerItems(rotation);
        }
    }
}
